#include "multicaster.h"

void network::multicaster::run()
{
	while(1) {
		if(is_interrupted()) {
			return;
		}
		boost::shared_ptr<network::message> msg = _message_q->get();
		// dispatching events...
		boost::mutex::scoped_lock l(_monitor);
		typedef list<network::multicaster::event_ptr>::iterator it;
		for(it i = _events.begin(); i != _events.end(); ++i) {
			if((*i)->get_type() == msg->type &&
			   (*i)->get_socket() == msg->sock) {
				boost::shared_ptr<network::event> e(
					new event(msg->node, *i, 
						  msg->new_sock));
				_event_q->put(e);
			}
		}
	}
}

void network::multicaster::add_handler(
	boost::shared_ptr<network::event_handler> h) 
{
	h->add_listener(boost::shared_ptr<network::multicaster>(this, 
							core::null_deleter()));
	boost::mutex::scoped_lock l(_monitor);
	_events.push_back(h);
}

void network::multicaster::remove_handler(
	boost::shared_ptr<network::event_handler> h) 
{
	boost::mutex::scoped_lock l(_monitor);
	_events.remove(h);
}

void network::multicaster::notify(const network::notifier *n)
{
	const network::event_handler *h = 
		dynamic_cast<const network::event_handler*>(n);
	if(!h) {
		return;
	}
	boost::mutex::scoped_lock l(_monitor);

	list<network::multicaster::event_ptr>::iterator i = _events.begin();
	list<network::multicaster::event_ptr>::iterator next = _events.begin();
	while(i != _events.end()) {
		++next;
		if(i->get() == h) {
			_events.erase(i);
		}
		i = next;
	}
}

